package hu.test.atacama;

import java.net.URL;
import java.util.ListIterator;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

public class MapActivity extends FragmentActivity implements
		OnMyLocationButtonClickListener {

	@Override
	protected void onPause() {
		unregisterReceiver(pathDownloaded);
		unregisterReceiver(commServiceReceiver);
		unregisterReceiver(commServiceError);
		super.onPause();
	}

	@Override
	protected void onResume() {
		super.onResume();

		int resultCode = GooglePlayServicesUtil
				.isGooglePlayServicesAvailable(getApplicationContext());

		if (resultCode == ConnectionResult.SUCCESS) {
			// Toast.makeText(getApplicationContext(),
			// "isGooglePlayServicesAvailable SUCCESS", Toast.LENGTH_LONG)
			// .show();
		} else {
			GooglePlayServicesUtil.getErrorDialog(resultCode, this,
					RQS_GooglePlayServices);
			finish();
		}

		registerReceiver(commServiceReceiver, commServIntentFilter);
		registerReceiver(commServiceError, commServErrorIntentFilter);
		registerReceiver(pathDownloaded, pathDrawIntentFilter);
	}

	static final LatLng CENTER_OF_HUNGARY = new LatLng(47.11, 19.30);
	final int RQS_GooglePlayServices = 1;

	private GoogleMap mMap;
	PolylineOptions lineOptions;
	Polyline polyline = null;

	CommServiceReceiver commServiceReceiver = new CommServiceReceiver();
	IntentFilter commServIntentFilter, commServErrorIntentFilter;
	IntentFilter pathDrawIntentFilter;
	Intent commServiceIntent;

	Common common;

	String currentObject = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_map);

		commServIntentFilter = new IntentFilter(CommService.COMMSERVICE_DONE);
		commServErrorIntentFilter = new IntentFilter(
				CommService.COMMSERVICE_ERROR);
		pathDrawIntentFilter = new IntentFilter(Common.PATH_ARRAY_FILL_COMPLETE);
		commServiceIntent = new Intent(getApplicationContext(),
				CommService.class);

		common = Common.getInstance(this);

		mMap = ((SupportMapFragment) getSupportFragmentManager()
				.findFragmentById(R.id.map)).getMap();
		if (mMap != null) {
			mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
			mMap.setMyLocationEnabled(true);
			mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
					CENTER_OF_HUNGARY, 6));

			if (common.markers != null) {
				for (MarkerOptions marker : common.markers) {
					if (marker != null) {
						Log.d(TAG, "adding marker");
						mMap.addMarker(marker);
					}
				}
			}

			common.displayToast(getString(R.string.message_map_markers_placed));

			mMap.setInfoWindowAdapter(new InfoWindowAdapter() {

				@Override
				public View getInfoWindow(Marker marker) {
					return null;
				}

				@Override
				public View getInfoContents(Marker marker) {
					View v = getLayoutInflater().inflate(R.layout.info_window,
							null);

					ImageView pictureView = (ImageView) v
							.findViewById(R.id.info_window_picture);
					TextView ownerNameTextView = (TextView) v
							.findViewById(R.id.info_window_owner_name);
					TextView licensePlateTextView = (TextView) v
							.findViewById(R.id.info_window_license_plate);
					TextView lastSeenTextView = (TextView) v
							.findViewById(R.id.info_window_last_seen);

					String[] details = marker.getSnippet().split(";");
					String ownerName, licensePlate;
					String deviceType = details[4];
					currentObject = deviceType + Common.SEPARATOR + details[5];

					if (deviceType.equals("android")) {
						ownerName = details[0];
						licensePlate = "";
					} else {
						ownerName = getString(R.string.text_info_window_owner)
								+ details[0];
						licensePlate = getString(R.string.text_info_window_license)
								+ details[1];
					}

					ownerNameTextView.setText(ownerName);
					licensePlateTextView.setText(licensePlate);
					lastSeenTextView
							.setText(getString(R.string.text_info_window_last_seen)
									+ details[2]);
					String pictureUrl = details[3];

					if (!pictureUrl.equals(Common.NO_PHOTO)) {
						try {
							Log.d(TAG, "pictureUrl: " + pictureUrl);
							URL url = new URL(pictureUrl);
							Bitmap picture = BitmapFactory.decodeStream(url
									.openConnection().getInputStream());
							pictureView.setImageBitmap(picture);
						} catch (Exception ex) {
							common.displayToast("MapActivity / getInfoContents: "
									+ ex.toString());
						}
					}
					return v;
				}
			});

			mMap.setOnMarkerClickListener(new OnMarkerClickListener() {

				@Override
				public boolean onMarkerClick(Marker marker) {
					mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
							marker.getPosition(), 15));
					return false;
				}
			});
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.map, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_legalnotices:
			String LicenseInfo = GooglePlayServicesUtil
					.getOpenSourceSoftwareLicenseInfo(getApplicationContext());
			AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(
					MapActivity.this);
			LicenseDialog.setTitle("Legal Notices");
			LicenseDialog.setMessage(LicenseInfo);
			LicenseDialog.show();
			return true;
		case R.id.menu_map_back:
			common.clearPathData();
			finish();
			return true;
		case R.id.menu_configure_path:
			configurePath();
			return true;
		case R.id.menu_draw_path:
			getPath();
			return true;
		case R.id.menu_show_path:
			if (polyline != null) {
				polyline.setVisible(true);
			}
			return true;
		case R.id.menu_hide_path:
			polyline.setVisible(false);
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	String TAG = "MapActivity";

	private void configurePath() {
		Log.d(TAG, "configurePath / start");
		AlertDialog.Builder alertMode = new AlertDialog.Builder(
				MapActivity.this);
		alertMode.setTitle(getString(R.string.menu_path_waypoints));

		String[] items = getResources().getStringArray(R.array.pathListOptions);
		alertMode.setItems(items, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				String pathOption = getResources().getStringArray(
						R.array.pathListValues)[which].toString();

				Log.d(TAG, "configurePath / selected something");
				Log.d(TAG,
						"numberOfWaypoints: " + common.getNumberOfWaypoints());
				Log.d(TAG, "pathOption: " + pathOption);
				Log.d(TAG, "pathData size: " + common.getPathData().size());
				if (Integer.parseInt(common.getNumberOfWaypoints()) != Integer
						.parseInt(pathOption)) {
					if (common.getPathData().size() > Integer
							.parseInt(pathOption)) {
						Log.d(TAG, "setNumberOfWaypoints 1");
						common.setNumberOfWaypoints(pathOption);
						drawPath(Integer.parseInt(pathOption));
					} else {
						Log.d(TAG, "setNumberOfWaypoints 2");
						common.setNumberOfWaypoints(pathOption);
						getPath();
					}
				}
				common.updateSharedPreferenceByKey(
						getString(R.string.key_path_waypoints), pathOption);
			}
		});
		alertMode.show();
	}

	private void getPath() {
		Log.d(TAG, "getPath");
		setProgressBarIndeterminateVisibility(true);

		String gpsData = "None";
		Long timeStamp = (long) 0;

		String metaData;
		if (currentObject != null) {
			metaData = currentObject + Common.SEPARATOR
					+ common.getNumberOfWaypoints();
		} else {
			metaData = common.getDeviceType() + Common.SEPARATOR
					+ Common.OWN_KEY + Common.SEPARATOR
					+ common.getNumberOfWaypoints();
		}
		Log.d(TAG, metaData);

		DataFromDevice dataFromDevice = new DataFromDevice(
				common.getDeviceType(), common.getSenderID(),
				common.getSerialNumber(), gpsData, timeStamp,
				Common.COMMAND_GET_PATH, metaData);

		commServiceIntent.putExtra("dataFromDevice", dataFromDevice);
		commServiceIntent.putExtra("startingMessage",
				getString(R.string.message_get_path));

		startService(commServiceIntent);
	}

	private void drawPath(int numberOfWaypoints) {
		Log.d(TAG, "drawPath");
		try {
			if (polyline != null) {
				polyline.remove();
				polyline = null;
			}

			lineOptions = new PolylineOptions();

			int firstElement = common.getPathData().size() - numberOfWaypoints;

			ListIterator<Coordinates> it = common.getPathData().listIterator(
					firstElement);
			while (it.hasNext()) {
				Coordinates wayPoint = it.next();
				lineOptions.add(new LatLng(Double.parseDouble(wayPoint
						.getLatitude()), Double.parseDouble(wayPoint
						.getLongitude())));
			}

			lineOptions.width(3);
			lineOptions.color(Color.RED);

			polyline = MapActivity.this.mMap.addPolyline(lineOptions);

		} catch (Exception ex) {
			common.displayToast("MapActivity / drawPath: " + ex.toString());
		}
	}

	private BroadcastReceiver pathDownloaded = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			setProgressBarIndeterminateVisibility(false);
			drawPath(common.getPathData().size());
		}
	};

	private BroadcastReceiver commServiceError = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			setProgressBarIndeterminateVisibility(false);
			common.displayToast("Commservice error");
		}
	};

	@Override
	public boolean onMyLocationButtonClick() {
		Log.d(TAG, "onMyLocationButtonClick");
		currentObject = "";
		currentObject = null;
		return false;
	}
}
